import math


class Entity(object):
    speed = 8  # frames per one-square movement

    def __init__(self, location, host):
        self.location = location
        self.host = host

        self._real_speed = self.speed
        self.turbo_time = 0
        self.turbo_left = 1
        self._movement_counter = 0  # when 0, can move
        self._facing = None  # direction facing
        self._queued_facing = None

    def do_move(self):
        self._movement_counter = max(
            0, self._movement_counter - 1
        )
        if self.turbo_time > 0:
            self.turbo_time -= 1
            if self.turbo_time == 0:
                self.speed = self._real_speed
        if self._movement_counter != 0 or self._queued_facing is None:
            return

        new_location = (
            self.location[0] + self._queued_facing[0],
            self.location[1] + self._queued_facing[1]
        )

        # Check if destination is passable. If so, do the move.
        # Then reset the movement counter.
        if self.host.maze[new_location]:
            self.location = new_location
            self._movement_counter = self.speed
            self._facing = self._queued_facing

        elif self._facing is not None:
            new_location = (
                self.location[0] + self._facing[0],
                self.location[1] + self._facing[1]
            )

            if self.host.maze[new_location]:
                self.location = new_location
                self._movement_counter = self.speed

    def process_event(self, ev):
        if ev.action == "CHANGE_DIRECTION":
            self._queued_facing = ev.direction
        elif ev.action == "ACTIVATE_TURBO":
            # Turbo can only be used once.
            if self.turbo_left > 0:
                self.turbo_left -= 1
                self._real_speed = self.speed
                self.turbo_time = 100
                self.speed = math.ceil(self.speed // 2)
        elif ev.action == "MOVE":
            print('(Cheating) MOVE event used to force move. This is cheating by AI or player.')
            self._facing = ev.direction
            self._movement_counter = 0
            self.do_move()


class Player(Entity):
    pass
